package cz.uhk.ppro.controllers.admin;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;

import java.util.List;

import cz.uhk.ppro.entities.Dil;
import cz.uhk.ppro.entities.Dodavatel;
import cz.uhk.ppro.entities.Stitek;
import cz.uhk.ppro.form.DilForm;
import cz.uhk.ppro.form.FiltrDily;
import cz.uhk.ppro.form.Login;
import cz.uhk.ppro.services.DilDbService;
import cz.uhk.ppro.services.DodavatelDbService;
import cz.uhk.ppro.services.LoginChecker;
import cz.uhk.ppro.services.StitekDbService;
import cz.uhk.ppro.validator.DilValidator;

@Controller
@SessionAttributes({"stitky", "dily", "dodavatele", "stitkyF"})
public class AdminMainController {
	Login login;
	DilDbService dilService;
	StitekDbService stitekService;
	DodavatelDbService dodavatelService;
	LoginChecker loginChecker;
	DilForm dilForm;
	DilValidator dilValidator;
	
	@Autowired
	public void setDilValidator(DilValidator dilValidator) {
		this.dilValidator = dilValidator;
	}

	@ModelAttribute("login")
	public Login getLogin() {
		return new Login();
	}
	
	@ModelAttribute("filtrDily")
	public FiltrDily getFiltrDily() {
		return new FiltrDily();
	}
	
	@Autowired
	public void setDilService (DilDbService dilService){
		this.dilService = dilService;
	}
	
	@Autowired
	public void setStitekService (StitekDbService stitekService){
		this.stitekService = stitekService;
	}
	
	@Autowired
	public void setDodavatelService (DodavatelDbService dodavatelService){
		this.dodavatelService = dodavatelService;
	}
	
	@Autowired
	public void setLoginChecker (LoginChecker loginChecker){
		this.loginChecker = loginChecker;
	}
	
	@ModelAttribute("dilForm")
	public DilForm getDilForm() {
		return new DilForm();
	}
	
	
	
	@RequestMapping("/adminHome")
	public String dily(Locale locale, ModelMap model, HttpSession session,
			@ModelAttribute("dilForm") DilForm dilForm,  @ModelAttribute("filtrDily") FiltrDily filtrDily) {
		if (loginChecker.checkLogin(session, "Admin")){
			List<Dil> dily = dilService.vypis();
			filtrDily = new FiltrDily();
			
			List<Stitek> stitky = stitekService.vypis();
			List<String> stitkyString = new ArrayList<String>();
			stitkyString.add("");
			for (Stitek s : stitky) {
				stitkyString.add(s.getNazevStitku());
			}
			
			List<Dodavatel> dodavatele = dodavatelService.vypis();
			
			model.addAttribute("dodavatele", dodavatele);
			model.addAttribute("stitky", stitky);
			model.addAttribute("stitkyF", stitkyString);
			model.addAttribute("dily", dily);
			model.addAttribute("filtrDily", filtrDily);
			return "adminHome";
		}else {
			return "accessDenied";
		}
	}
	
	@RequestMapping("/adminSmazDil")
	public String del(Locale locale, ModelMap model, HttpSession session,
			@ModelAttribute("dilForm") DilForm dilForm,int id) {
		
		if (loginChecker.checkLogin(session, "Admin")){
			dilService.smaz(dilService.vrat(id));
			return "redirect:/adminHome";
		}else {
			return "accessDenied";
		}
	}
	
	@RequestMapping(value="/adminUpravDil", method = RequestMethod.GET)
	public String edit(Locale locale, ModelMap model, HttpSession session,
			@ModelAttribute("dilForm") DilForm dilForm,
			int id) {
		
		if (loginChecker.checkLogin(session, "Admin")){
			
			Dil dil = dilService.vrat(id);
			dilForm.setDil(dil);
						
			List<Stitek> stitky = stitekService.vypis();		
			List<Dodavatel> dodavatele = dodavatelService.vypis();
			
			model.addAttribute("dodavatele", dodavatele);
			model.addAttribute("stitky", stitky);
			return "/adminUpravDil";
		}else {
			return "accessDenied";
		}
	}
	
	@RequestMapping(value = "/adminUpravDil", method = RequestMethod.POST)
	public String editPost(@ModelAttribute("dilForm") DilForm dilForm, BindingResult result,
			Locale locale, ModelMap model,  HttpSession session	) {
		dilValidator.validate(dilForm, result);
		if (result.hasErrors()) {		
			 return "adminUpravDil";
		 } else {
		if (loginChecker.checkLogin(session, "Admin")){
			Dil dil = dilService.vrat(dilForm.getId());
			dilService.uprav(dil, dilForm.getKatalogoveCislo(), 
					dilForm.getNazev(), dilForm.getPoznamka(), dodavatelService.vratDodavatele(dilForm.getDodavatel()));
			stitekService.odrad(dil);
			 for (int st : dilForm.getStitky()) {
                 stitekService.prirad(stitekService.vrat(st), dil);
			 }   
			return "redirect:/adminHome";
			
		}else {
			return "accessDenied";
		}}
	}
	
	 @RequestMapping("/adminPridejDil")
     public String add(@ModelAttribute("dilForm") DilForm dilForm, BindingResult result,
    		 Locale locale, ModelMap model, HttpSession session) {
		 dilValidator.validate(dilForm, result);
		 if (result.hasErrors()) {
				return "adminHome";
		 } else {
             if (loginChecker.checkLogin(session, "Admin")){
                     Dil dil = new Dil();
                     dil.setKatalogoveCislo(dilForm.getKatalogoveCislo());
                     dil.setNazev(dilForm.getNazev());
                     dil.setPoznamka(dilForm.getPoznamka());
                     dil.setDodavatel(dodavatelService.vratDodavatele(dilForm.getDodavatel()));
                     dilService.pridej(dil);
                     
                     for (int st : dilForm.getStitky()) {
                             stitekService.prirad(stitekService.vrat(st), dil);
                     }                 
                     return "redirect:/adminHome";
             }else {
                     return "accessDenied";
             }
     }}
	 
	 @SuppressWarnings({ "unchecked", "rawtypes" })
		@RequestMapping("/adminFiltrujDily")
	    public String filtruj(ModelMap model, HttpSession session, @ModelAttribute("filtrDily") FiltrDily filtrDily) {
			//http://www.devx.com/java/Article/28754/1954 ten první dlouhej způsob, je pochopitelnější		
			Map parameters = new HashMap();
			boolean firstClause = true; 
			StringBuffer queryBuf = new StringBuffer("from Dil d");
			String stitek = filtrDily.getStitek();
			String nazev = filtrDily.getNazev();
			String katCislo = filtrDily.getKatCislo();
			List<Dil> dily;
			
			 if (stitek.compareTo("") != 0) {
			        //queryBuf.append(firstClause ? " where " : " and "); //není třeba, bude to případně vždy první
			        
				 	queryBuf.append(" join d.stitky s where s.nazevStitku in :stitek");
				  	
			        parameters.put("stitek",stitek);
			        firstClause = false;
			    }    
			    if (nazev.compareTo("")!=0) {
			        queryBuf.append(firstClause ? " join d.stitky s where " : " and "); //join aby to vracelo ve stejném formátu
			        queryBuf.append("d.nazev like :nazev");
			        parameters.put("nazev","%"+nazev+"%");  // % je wildcard - *
			        firstClause = false;
			    }
			    if (katCislo.compareTo("")!=0) {
			        queryBuf.append(firstClause ? " join d.stitky s where " : " and ");
			        queryBuf.append("d.katalogoveCislo like :katCislo");
			        parameters.put("katCislo","%"+katCislo+"%");
			        firstClause = false;
			    }
			if (!firstClause){
				String query = queryBuf.toString();
				List<Object[]> dilydb = dilService.vypisKriteria(query, parameters);
				dily = new ArrayList<Dil>();
				for (Object[] o : dilydb){
					dily.add((Dil)o[0]);
				}
			} else {
				dily = dilService.vypis();
				}
			model.addAttribute("dily", dily);
			return "adminHome";
	    }
}
